﻿// Copyright (c) 2014 Bryan C. O'Connell
// http://wsubi.codeplex.com/license
// Purpose: Defines the 'list' command. This command searches for and displays 
// the names of scripts matching the criteria specified by the user.

// TODO: List is a reserved class name. Change to 'show', 'find', etc.

using System;
using System.Collections.Generic;
using Wsubi.Code.Utilities;

namespace Wsubi.Code.Commands
{
    public class List : ICommand
    {
        public string Target { get; set; }
        public string Params { get; set; }
        public ScriptData ScriptDataStorage { get; set; }

        private ResultSet _Results;

        private enum ListCommandType { All, MatchesFirstCharacter, FileType }

        public string GetActionKeyword() {
            return "list";
        }

        public ResultSet Execute()
        {
            Guard.CheckForNullObject(ScriptDataStorage);            

            ListCommandType RequestedType = DetermineRequestedType();
            List<string> ListOfMatches = new List<string>();
            ListOfMatches = SearchForScripts(RequestedType);

            BuildResultSet(ListOfMatches);
            return _Results;
        }        

        private ListCommandType DetermineRequestedType()
        {
            Guard.CheckForEmptyString(Target);

            Char FirstCharOfTarget = Target[0];
            ListCommandType CurrentType;

            if (FirstCharOfTarget == '*') {
                CurrentType = ListCommandType.All;
            } 
            else if ( (Char.IsLetter(FirstCharOfTarget)) || (Char.IsNumber(FirstCharOfTarget)) ) {
                CurrentType = ListCommandType.MatchesFirstCharacter;
            }
            else if ( (FirstCharOfTarget == '.') && (Target.Length > 1) ) {
                CurrentType = ListCommandType.FileType;
            }
            else {
                throw new ArgumentException("The target specified in the requested 'list' command was not valid.");
            }

            return CurrentType;
        }

        private List<string> SearchForScripts(ListCommandType TypeOfList)
        {
            List<string> ListOfMatches = new List<string>();
            string[] ListOfScripts = ScriptDataStorage.ShareListOfScripts();

            Guard.MinimumNumberOfArrayElements(ListOfScripts, 1);

            if (TypeOfList == ListCommandType.All) {
                ListOfMatches = new List<string>(ListOfScripts);
            }

            if (TypeOfList == ListCommandType.MatchesFirstCharacter) {
                string FirstChar = Target[0].ToString().ToLower();
                ListOfMatches = new List<string>(Array.FindAll(ListOfScripts, ScriptName => ScriptName.ToLower().StartsWith(FirstChar)));
            } 

            if (TypeOfList == ListCommandType.FileType) {
                ListOfMatches = new List<string>(Array.FindAll(ListOfScripts, ScriptName => ScriptName.ToLower().EndsWith(Target.ToLower())));
            }

            return ListOfMatches;
        }

        private void BuildResultSet(List<string> ResultsToSave)
        {
            _Results = new ResultSet();
            _Results.SaveResults(ResultsToSave);
            _Results.OutputTo = OutputsTo.Screen;
        }
    }
}
